/*
                         \\\|///
                       \\  - -  //
                        (  @ @  )
+---------------------oOOo-(_)-oOOo----------------------+
|                                                        |
|                   FreeRTOS V9.0.0 + STM32              |
|                      1A1 board Demo                    |
|                        2020.08.14								       |
|                  Thermofisher Scientific               |
|                ming.liu2@thermofisher.com              |
|           https://gitee.com/STM32_FreeRTOS_1A1.git     |
|																												 |
|                             Oooo                       |
+-----------------------oooO--(   )----------------------+
                       (   )   ) /
                        \ (   (_/
                         \_)     
*/
 

#include "FreeRTOS.h"
#include "task.h"

#include "bsp_usart.h"
#include "bsp_key.h"
#include "led_task.h"
#include "bsp_uart5.h"
#include "cmd_parse.h"
#include "modbus_rtu.h"

static TaskHandle_t AppTaskCreate_Handle = NULL;/* Create task handle */
static TaskHandle_t LED_Task_Handle = NULL;
static TaskHandle_t Test_Task_Handle = NULL;


uint8_t *Test_Ptr = NULL;


static void AppTaskCreate(void);

static void LED_Task(void* pvParameters);
static void Test_Task(void* pvParameters);

static void BSP_Init(void);


int main(void)
{
  BaseType_t xReturn = pdPASS;

  BSP_Init();
	printf("This is FreeRTOS test Demo\n");
  printf("LiuMing created @2020-08-15 \n");

  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* task entry func */
                        (const char*    )"AppTaskCreate",/* task name */
                        (uint16_t       )512,  		/* task stack */
                        (void*          )NULL,		/* entry param */
                        (UBaseType_t    )5, 			/* task priority */
                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* Task handler */ 
          
  if(pdPASS == xReturn)
    vTaskStartScheduler();   /* start task */
  else
    return -1;  
  
  while(1);   /* It won't execute here */    
}


static void AppTaskCreate(void)
{
  BaseType_t xReturn = pdPASS;
  
  taskENTER_CRITICAL();

	led_task_create(); //LM add
	cmd_parse_create();
	dat_initDatabase();
  
//  xReturn = xTaskCreate((TaskFunction_t )Test_Task,  /* 任务入口函数 */
//                        (const char*    )"Test_Task",/* 任务名字 */
//                        (uint16_t       )512,  /* 任务栈大小 */
//                        (void*          )NULL,/* 任务入口函数参数 */
//                        (UBaseType_t    )3, /* 任务的优先级 */
//                        (TaskHandle_t*  )&Test_Task_Handle);/* 任务控制块指针 */ 
//  if(pdPASS == xReturn)
//    printf("创建Test_Task任务成功\n\n");
  
  vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
  
  taskEXIT_CRITICAL();            //退出临界区
}



/**********************************************************************
  * @ 函数名  ： LED_Task
  * @ 功能说明： LED_Task任务主体
  * @ 参数    ：   
  * @ 返回值  ： 无
  ********************************************************************/
static void LED_Task(void* parameter)
{	
  while (1)
  {
    LED1_TOGGLE;
    vTaskDelay(1000);/* 延时1000个tick */
  }
}


static void Test_Task(void* parameter)
{	 
  uint32_t g_memsize;
  while (1)
  {
    if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )
    {
      /* KEY1 被按下 */
      if(NULL == Test_Ptr)
      {
                  
        /* 获取当前内存大小 */
        g_memsize = xPortGetFreeHeapSize();
        printf("系统当前内存大小为 %d 字节，开始申请内存\n",g_memsize);
        Test_Ptr = pvPortMalloc(1024);
        if(NULL != Test_Ptr)
        {
          printf("内存申请成功\n");
          printf("申请到的内存地址为%#x\n",(int)Test_Ptr);

          /* 获取当前内剩余存大小 */
          g_memsize = xPortGetFreeHeapSize();
          printf("系统当前内存剩余存大小为 %d 字节\n",g_memsize);
                  
          //向Test_Ptr中写入当数据:当前系统时间
          sprintf((char*)Test_Ptr,"当前系统TickCount = %d \n",xTaskGetTickCount());
          printf("写入的数据是 %s \n",(char*)Test_Ptr);
        }
      }
      else
      {
        printf("请先按下KEY2释放内存再申请\n");
      }
    }
    if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )
    {
      /* KEY2 被按下 */
      if(NULL != Test_Ptr)
      {
        printf("释放内存\n");
        vPortFree(Test_Ptr);	//释放内存
        Test_Ptr=NULL;
        /* 获取当前内剩余存大小 */
        g_memsize = xPortGetFreeHeapSize();
        printf("系统当前内存大小为 %d 字节，内存释放完成\n",g_memsize);
      }
      else
      {
        printf("请先按下KEY1申请内存再释放\n");
      }
    }
    vTaskDelay(20);/* 延时20个tick */
  }
}

/***********************************************************************
  * @ 函数名  ： BSP_Init
  * @ 功能说明： 板级外设初始化，所有板子上的初始化均可放在这个函数里面
  * @ 参数    ：   
  * @ 返回值  ： 无
  *********************************************************************/
static void BSP_Init(void)
{
	/*
	 * STM32中断优先级分组为4，即4bit都用来表示抢占优先级，范围为：0~15
	 * 优先级分组只需要分组一次即可，以后如果有其他的任务需要用到中断，
	 * 都统一用这个优先级分组，千万不要再分组，切忌。
	 */
	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
	

	MB_uart5_init();
	/* 串口初始化	*/
//	USART_Config();
  
  /* 按键初始化	*/
  //Key_GPIO_Config();

}

/********************************END OF FILE****************************/
